S100 Computers

HomeS-100 Boards HistoryNew BoardsSoftwareBoards For Sale
ForumOther Web SitesNewsIndex  
  
A S-100 CPLD based 80386 CPU Board (V2 - 80386 CPU Board).
  
  
 V2 80386 Board
  
Our 74LSxx based 80386 board seems to function correctly and has been used by our users for some time now.   The next step is to create an equivalent 80486 CPU board.  This as we will see will require the swapping of a number of discrete 74LSxx chips with a  CPLDs not only to get everything to fit on one S100 board, but to take advantage of some of the extra properties the 80486 possesses.  There are added complexities in the way the 80486 address the data bus over the 80386.  This would require a large number of 74LSxx chips. 

In order to ease the transition in going from a 80386 to 80486 board utilizing a CPLD interface,  I decided to first convert our 80386 board into a CPLD driven version.  Not only did this simplify the design, but it allowed for a much more robust CPU board.  I should point out however that this board is just a transition prototype, the "old" 74LSxx board works fine.  To understand the text below, if you have not already done so you should read the write-up on the original 80386 S100 board first from here.

At first I first tried using GAL's for this board.  The complete schematic for an early GAL based 80386 board can be found here.  Just by way of illustrating the years worth of effort this took,  here is a picture of the major prototype versions along the way:
  
   
 Prototype 80386 Boards
    
D
uring the course of this process it became clear that the number of required 22V10 GALs was going to be significant, ending up somewhere between 6 to 8. One reason for this was that the same input signals had to be fed in over and over to the different GALs.  This not only was inefficient but it increased the number of traces on the board. 
 
It became apparent that a single "Complex Programmable Logic Device" CPLD could do the job on many GAL's.  CPLDs were essentially the next evolutionary logic chips after GALs.  They can be viewed as just bigger GAL's.  See here for an introduction to CPLDs.  The final design ended up with one ATM 1508 CPLD and one 22V10 GAL is shown at the top of this page.
  
You can see the one large CPLD in the center of the board.

Here is a schematic of the ATM 1508 CPLD circuit for this CPLD based 80386 board:-
  
 CPLD Circuit
     
As you can see most of the input signals to several GAL's are now concentrated into a single 68 pin chip.  In fact besides the CPU, data and address line buffers there are few other chips on the board.  There would be even less if we did not want to have control over the wait state circuits for the RAM, I/O and INTA R/W signals with external jumpers. As with the above original "74LSxx"   based board, we need to delay the CPU driven S100 bus pWR* signal.  This time however rather than hard code it with a 74LS175 chip (as we did in the 74LSxx based 80386 board), we will do it in in software within the CPLD.   

One very fortunate thing about the 80386 is that in 16 bit mode the upper 16 bits of a 32 bit data transfer is shifted down to the lower 16 bits. 
This considerably simplifies the S100 bus interface.  This is not the case as we will see for the 80486 CPU.

Let us step through the various functions/code this CPLD supplies.


1. Activate the board.
The current software assumes this 80386 board will act as an S100 bus slave.
Later if needed, it can be modified/jumpered as being a bus master.
In hardware one of the TMA lines (Jumper P13) goes low to start the master/slave transfer process.
Sequentially XFERI & XFERII are then activated (and the S100 bus clock signal PHI, then originates from this board).

Pinnode = [reg2..0];                       /* Need 3 D type Flip Flops */

reg0.d = TMAx;                             /* TMAx goes low-> high */
reg0.ckmux = !PHI;
reg0.ar = !MASTER_RESET;                   /* Return to high on reset */
!S100_HOLD = reg0;                         /* Lower S100 bus HOLD* line */

!XFERI = reg0 & pHLDA;                     /* Activate the S100 bus Control lines, when HLDA comes back */
                                           /* Note we inactivate U55 for RAM > 16M in protected mode */
reg1.d = reg0;
reg1.ck = pHLDA;                           /* S100 bus grants bus by raising pHLDA line */
reg1.ar = !reg0;

BOARD_ACTIVE = reg1;                       /* HIGH when transfer comes to 80386 Board */
!XFERII = reg1;                            /* LOW to activate S100 bus Status, Data & Address lines */

reg2.d = reg1;
reg2.ckmux = !PHI;
reg2.ar = !reg1;

!RESET_80386 = !XFERI;                     /* Activate the CPU, lower it's reset pin */
SPARE = RESET_80386;                       /* Use "SPARE" LED as a diagnostic flag */

CPU_HOLD = 'b'0;                           /* CPU HOLD always low for Slave mode */



2.  The Clock Generator/Divider Circuit
We will divide a 60 MHz (or higher),  Oscillator down to obtain the CPU and S100 bus clocks.  CLK2 is the CPU clock, it is always 2X the bus clock for the 80386. Remember CLK becomes PHI on S100 bus via U47.  It is a different speed when Z80 is bus master, so PHI is not the same as CLK.

Pinnode = [CD3..0];
 
                               /* 80  70    60   36   32   30                  MASTER_CLK */

CD0.t = 'b'1;                  /* 40  35    30   18   16   15                             */

CD1.t = CD0;                   /* 20  17.5  15    9    8    7.5 <----- S100 Bus PHI Speed */

CD2.t = CD0 & CD1;             /* 10   8.5  7.5   4.5  4    3.25                          */

CD3.t = CD0 & CD1 & CD2;       /*  5   4.75 3.25  2.25 2    1.6                           */

[CD3..0].ckmux = MASTER_CLK;

CPLD_CLK2 = (CD1 & !LS100_SEL)                      /* CPU Clock, for S100 bus access (15 MHz) */
# (CD0 & LS100_SEL);                                /* CPU Clock, for > 16MB PM Access (30 MHz) */

CPLD_CLK = CD2;                                     /* S100 bus Clock, always (7.5 MHz) */
WAIT_CLK = CD1;                                     /* Run wait state generator from CLK2 */

In the above we setup three toggle flip flops.  We divide the input oscillator by two each time.   Remembering that the CLK2 is twice the speed of CLK (PHI).   For S100 bus access we will run CLK2 and CLK/PHI at 15 & 7.5 MHz.   In Protected mode (> 16MB RAM) we run CLK2 at 32 MHz (CLK is not used with our daughter RAM boards).   The only fly in the ointment is when we switch clock speeds.   We have to be careful not to generate runt clock cycles.  In the 74LXxx based 80386 board we used a 74LS74 chip (Clocked by CLK2)  to do this. We do it here in software (see below).   Note, the upper speed limit of these ATF 1508's is about 150MHz, so we could later add more flip flops and get more speed options.  Not all S100 systems may be able to work at 7.5MHz, so even with the above you might want to start with a 40-70MHz range of oscillators.  For some reason using lower speed oscillators (with less FF dividers) does not seen to be as reliable.


3. Activated and latch the LS100_SEL* signal.
The CPU will be talking to two completely separate RAM circuits. For RAM below 16MB it will address RAM on the S100 bus. Any RAM above this address space will be assumed to be on the extended bus using the overhead connectors. All port I/O's and Interrupts will also be on the S100 bus.  The relevant signal that defines which bus the CPU is talking two is the S100_SEL signal. If it is low the S100 bus is being addressed. If it is high the "overhead bus" is being addressed.  The extra complication is that when addressing the overhead bus the CPU's clock (CLK2) is doubled -- because that bus can handle a much faster speed.

Pinnode = S100_SEL;                               
Pinnode = SLAVE_ACTIVE;                  /* SLAVE_ACTIVE HIGH if 80386 has control of the bus */
                                         /* HIGH if RAM > 16M else LOW */

S100_SEL = (A24 # A25 # A26 # A27 # A28 # A29 # A30 # A31) & LMIO & BOARD_ACTIVE;

LS100_SEL.d = S100_SEL;                  /* Latch/change the LS100_SEL signal ONLY on a CLK2 transition */
LS100_SEL.ck = CLK2;                     /* To avoid clock switching in the middle of a cycle */



4. Synthesize the Address lines A0 & A1 & sXTRQ* from the CPU BE3*... BE0*
This is fairly straightforward. We also need to generate the S100 bus signal sXTRQ for 16 bit access from the 80386 signals:-


mA1 = mBE0 & mBE1;                         /* Signals are latched by U75 before appearing on the S100 bus */

mA0    = (mBE0 & !mBE1 & !mBE2)
        #(mBE0 & !mBE1 & mBE2)
        #(mBE0 & mBE1 & mBE2);

msXTRQ  = (mBE1 & mBE3)                    /* Note this signal is later latched by U117 for the S100 bus */
         # mA0;


5. Synthesize the S100 Bus Control and Status signals
This is the very heart of the board. We need to carefully reformulate the main 80386 control signals to their S100 bus counterparts.
After much trial and  error this is what I ended up with:-

Pinnode = CPU_MEM_RD;
Pinnode = CPU_MEM_WR;

!IO_OUT = !LMIO & LDC & LWR & ADS;                         /* I/O Write */

!IO_IN = !LMIO & LDC & !LWR & ADS;                         /* I/O read */

CPU_MEM_WR = LMIO & LDC & LWR & ADS;

CPU_MEM_RD = ((LMIO & !LDC & !LWR & ADS)
           # (LMIO & LDC & !LWR & ADS));


!MEM_WR = CPU_MEM_WR & !LS100_SEL;                         /* RAM Write (data) for S100 bus only */

!MEM_RD = CPU_MEM_RD & !LS100_SEL;                         /* RAM code read for S100 bus only */

!INTA = !LMIO & !LDC & !LWR & ADS;

!HALT = LMIO & !LDC & LWR & ADS;


!ssM1 = ((LMIO & !LDC & !LWR)                              /* RAM code read for S100 bus only */
      # (!INTA)); /* INTA */

ssWO = (!IO_OUT                                            /* I/O Write */
      # !MEM_WR                                            /* RAM Write */
      # !INTA);                                            /* INTA (ALL) */


!dpWR = ((!IO_OUT & !Delay2)                               /* Delayed I/O Write (ALL) */
      #  (!MEM_WR & !Delay2));                             /* Delayed RAM Write (S100 Bus only) */


ppDBIN = ((!MEM_RD & INTA)                                 /* RAM read (S100 Bus only) */
        # (!IO_IN & INTA));                                /* I/O read (ALL) */


!EXT_RAM_RD = CPU_MEM_RD & LS100_SEL;                      /* RAM Read signal for overhead bus */

!EXT_RAM_WR = CPU_MEM_WR & LS100_SEL;                      /* RAM Write signal to overhead bus */


All this is based on the data sheets Intel and AMD supplied that describes the levels of the critical M/IO, D/C and R/W control lines send out by the CPU.   See here for more details. Note these lines going into the CPLD are first latched via U177 (a 74LS75).    For the S100 bus the problematic signal is the main pWR* signal. It comes out too early on the 80486 and must be delayed from appearing on the bus.  The "Delay_2" signal is provide by the jumper P101 (see below). Somewhere between 1 and 3 CLK2 cycles seems best. However its value must always be less than the RAM, I/O and INTA delays (see below).

In the first version of this board I sent these three lines over the top of the board (via the ribbon cable connector) to the 32 bit RAM boards.  These boards would decode the signals to generate the corresponding RAM read and write signals.   I found it is more reliable to do the decoding on this board and just send the RAM read or write signals directly.    The two signals EXT_RAM_RD and EXT_RAM_WR are these signals.  There are jumpers (K103 & K106)  to utilize the "old" signals if you wish to utilize the earlier RAM boards.  All newer extended RAM boards (see below) however will utilize these two signals only.



6.  Generate CPU Ready* signal.
If READY is HIGH then the CPU will add wait states until it is LOW again.  The clock going to the wait state generator circuit (U102 & U103) is CLK2, so each jumper setting is 2 CLK2 cycles or 1 CLK cycle --  an actual  S100 bus cycle wait state. That said, even at 8MHz the S100 bus the board requires 4 and 5  wait states for RAM and I/O access.  

Note in protected mode when access the overhead RAM boards the above wait states are not inserted.  Those boards have their own wait state generator which returns the "DB_WAIT" signal to request a wait state.  With a 32 MHz CLK signal only a single CLK2 wait state is required with our current overhead RAM boards. 

READY     =     ((!S100_WAIT & !LS100_SEL)                                                  /* XRDY or RDY low, then S100_READY goes HIGH */
                 #    (!CPU_WAIT & !LS100_SEL)                                                    /* RAM_WAIT, IO_WAIT or INTA_WAIT then CPU_WAIT is LOW*/
                 #    (!DB_WAIT & LS100_SEL));

S100_WAIT is generated by the two S100 bus wait request signals XRDY* and RDY* via U114. 
CPU_WAIT  is generate on this board to slow down the CPU for RAM and I/O access.  it is fed  by three separate rows of jumpers to insert wait states for RAM, I/O and INTA bus cycles.  

7. Generate buffer control signals for 8/16 bit CPU transfers to S100 bus data lines using the  IEEE-696 protocol
One nice thing about using a CPLD is there is now ample room to lay down detailed equations so we can convert the 8 or 16 bit data signals to/from the 80386 and redirect them to the appropriate 8 or 16 bit S100 bus data lines.  If you are not familiar with the unique way the S100 bus handles 8 and 16 bit data please see here first.  Here are the relevant equations:-

!U104_OE  = ((!MEM_RD & !msXTRQ & !LS100_SEL)                /* U104, HIGH 16 Bit MEM CPU READ (DI0-7) */
          # (!MEM_WR & !msXTRQ & !LS100_SEL)                 /* HIGH 16 Bit MEM CPU WRITE (DI0-7) */
          # (!IO_IN & !msXTRQ & !LS100_SEL)                  /* HIGH 16 Bit I/O CPU READ (DI0-7) */
          # (!IO_OUT & !msXTRQ & !LS100_SEL)                 /* HIGH 16 Bit I/O CPU WRITE (DI0-7) */
          # (!MEM_RD & msXTRQ & mA0 & !LS100_SEL)            /* HIGH 8 bit MEM CPU READ (DI0-7) */
          # (!IO_IN & msXTRQ & mA0 & !LS100_SEL));           /* HIGH 8 bit I/O CPU READ (DI0-7) */


!U112_OE  = ((!MEM_RD & !msXTRQ & !LS100_SEL)                /* U112, LOW 16 Bit MEM CPU READ (DO0-7)*/
          # (!MEM_WR & !msXTRQ & !LS100_SEL)                 /* LOW 16 Bit MEM CPU WRITE (DI0-7) */
          # (!IO_IN & !msXTRQ & !LS100_SEL)                  /* LOW 16 Bit I/O CPU READ (DI0-7) */
          # (!IO_OUT & !msXTRQ & !LS100_SEL)                 /* LOW 16 Bit I/O CPU WRITE (DI0-7) */
          # (!MEM_WR & msXTRQ & !mA0 & !LS100_SEL)           /* LOW 8 bit MEM CPU READ (DO0-7) */
          # (!IO_OUT & msXTRQ & !mA0 & !LS100_SEL));         /* LOW 8 bit I/O CPU READ (DO0-7) */


!U106_OE  = ((!MEM_RD & msXTRQ & !mA0 & !LS100_SEL)          /* U106 LOW 8 bit MEM CPU READ (DI0-7) */
          # (!IO_IN & msXTRQ & !mA0 & !LS100_SEL)            /* LOW 8 bit I/O CPU READ (DI0-7) */
          # !INTA & !LS100_SEL);                             /* INTA vectors are always on 80386 LOW data bits 0-7 */

!U105_OE = ((!MEM_WR & msXTRQ & mA0 & !LS100_SEL)            /* U105, HIGH 8 bit MEM CPU WRITE ((DO0-7) */
         # (!IO_OUT & msXTRQ & mA0 & !LS100_SEL));           /* HIGH 8 bit I/O CPU READ */

No longer are we shifting 8 bits to/from the Data In/Out S100 bus lines as we had to do with out 8086, and 80286 CPU boards. This makes for a much more reliable approach.



8. Generate the S100 Bus pSYNC and pSTVAL signals  
Finally we need a few housekeeping signals. We will generate the S100 bus signal pSTVAL (Low) = ADS (CPU Low), Synchronized against it with the falling ADS* signal.  We will generate the S100 bus signal pSync (High) = /ADS (CPU Low), (pSYNC is inverse of pSTVAL on this board).

ppSTVAL.ckmux =  CLK;
ppSTVAL.d     =  ADS;                    /* ADS Active LOW so in STVAL */
ppSync        = !ppSTVAL;                /* pSYNC is active high */

All the above code can be quickly and easily generated utilizing the Atmel "WinCupl" Windows IDE interface.  You can read more about this interface here.
     
 CUPL_IDE

I still retained one 22V10 GAL to handle the master/slave switching circuit described above.  However now the GAL code was further condensed so as not even need a 74LS74 flip-flop as we did in the earlier prototype 80386 boards. Here is the PALASM code:-

;---------------------------------- PIN Declarations ---------------
PIN 1 PULSE_IN ;CLK pin, input from pin 23 (PULSE_OUT)
PIN 2 A0                 ;Note these are actual S100 bus address lines (outside the 80386)
PIN 3 A1
PIN 4 A2
PIN 5 A3
PIN 6 A4
PIN 7 A5
PIN 8 A6
PIN 9 A7
PIN 10 A8
PIN 11 A9
Pin 12 GND

Pin 13 A10
Pin 14 A11
Pin 15 A12
Pin 16 A13
Pin 17 A14
Pin 18 A15
Pin 19 pDBIN              ;S100 bus port write
Pin 20 sINP               ;S100 bus status Port IN line
Pin 21 /RESET             ;Active LOW reset pulse from S100 bus
Pin 22 TMAXPU             ;Toggle bit to TMA 1-4 (inversed)
Pin 23 PULSE_OUT          ;Pulse to clock pin 1 input

;----------------------------------- Boolean Equation Segment ------

EQUATIONS

/PULSE_OUT =   A0 * /A1 * A2 * A3 * /A4 * A5 * A6 * A7              ;Port EDH = 1110 1101
            * /A8 * /A9 * /A10 * /A11 * /A12 * /A13 * /A14 * /A15
            * sINP * pDBIN
            + RESET * TMAXPU                                        ;Clock LOW if HIGH with reset

TMAXPU    := /TMAXPU * /RESET                                       ;Toggle
           + RESET
 

Here is the relevant circuit:-  
  
 GALSwitch


Step By Step Building the CPLD Based 80386 CPU Board.
The first step is to examine the bare board carefully for scratches or damaged traces. Use a magnifying glass if need be. The quality of the boards we get is excellent. I must have done over 100 different boards by now, never had a problem, but there is always a first time. A broken trace is almost impossible to detect by eye on a completed board.

Next solder in all the required IC sockets, resistors, resistor arrays, capacitors, jumpers.  Do not install the LED's at this stage.  remember C67, C68, C69, C122 and C123 are  47pF caps, and C51 & C74 are 1uF caps.  Don't forget R24 & R26 (two 20K) resistors within the CPU socket area as well as the two 0.1uF caps. Do not install the top ribbon connectors P10 and P12 at this stage.

On this board (if relevant) the + terminal will have a square pad.  Likewise for jumpers and resistor arrays pin 1 will have a square pad.  Be sure you put the resistor arrays in with the correct orientation of pin 1. Check their values also before soldering (they are difficult to remove).  Make sure you have arrays that have a common pin 1.

You can use cheaper "double swipe" IC sockets. However for a critical board like this I prefer to use "Machine Tooled" IC sockets (e.g. Jameco # 38623).  Unfortunately they are more expensive and you have to be particularly careful not to bend the IC pins.  The two clock oscillators should have their own special sockets (e.g. Jameco #133006).  However if you like you can solder the 2MHz oscillator directly to the board since it never changes.   The traces on this board are quite dense. Do not slobber solder all over pins. Only a small amount i is needed.  In particular be careful the 80386 and CPLD sockets are soldered close to the board surface. Use tape to hold them in place during soldering.  A solder bridge on the front side would be hard to find.  I actually like to have a 0.5mm space between the back of the socket and the front of the board to guard against solder flow between pins under the socket.  Probably being paranoid!

Its good to check there are no board shorts at this stage. Insert the board into the bus with no other slave CPU boards in your system.  Show that you can boot up your system. If not, you have a serious solder bridge somewhere on the board.  Before you do anything else with a magnifying glass go over every socket on the board and examine for a proper solder joint. I like to "reheat" each joint just to be on the safe side.  It's easy not to have a good solder joint for the ground pins.  Double check.   Extra time here will save you hours later!  

Insert the 5V Regulator (A TO-3 LM323K or preferably a Pololu Regulator or EzSBC 3A, 5V unit) The 2.5A Pololu fine, I happen to use the EzSBC regulator on this board.  Insert the board back into your system and verify you have 5 volts (+/- -0.1 volts) on the relevant IC pins.

Next install the 5 LED's.  Generally the longest lead goes into the square hole. I usually check by grounding the appropriate pin on U66 with a probe before soldering them in.   Colors are up to you. I always use blue for board select in my system. Here I use red for S100_SEL* and yellow for HALT.  Install a 30MHz Oscillator in P103 and a 2MHz Oscillator in P55 (if you have not directly soldered the latter to the board).

Somewhat counterintuitive we next need to program the CPLD.  This is because the pins are undefined until they are programmed.  Actually I think you are OK with an unused chip (all pins are inputs) but for a previously used one some pins may be pointing in the wrong direction.  Place the ATM-1508 in its socket, hookup the CPLD programmer and burn in the 80386.JED file (see below).  
     
First we will add the GAL circuit to switch in/out the board for the master/slave setup on the bus.   In your system you need to have the Z80 CPU board, a RAM board like our 4 or 16MB board, a console I/O board and the  MSDOS Support board  (or at least the 8086 or 80386  monitor in the top 1MB RAM space).  Remember the 80386 always initializes at FFFF0H.  

Program and add the 22V10 GAL to U9.  Add U79 and U101. Jumper P36 1-2.
Place the board in your system and from the Z80 monitor query in port 0EDH.   Pin 2 of P36 should go low.  Query in again, it should return high.
If you have our V2 SMB, jumper P32 3-4. Then  if you query out  port EE, 01 then the TMA0* S100 line should go low likewise. Either mode can be used to transfer bus control to this board.

Install the address line buffers U73, U74 and U75. Install U108, U107, ,JP 103, U111 and U110. Jumper K102 2-3 for now. 
Install U66 and jumper and K3 2-3 for now.  Add U49 and IC1.  Jumper K107 2-3, and add JP101.
Pin 8 of U49 is an OC output.  The board is missing a 1K pull-up resistor.
On the back of the board connect a 1K resistor to U49 pin 8 and Vcc (pin 1 of K104).
Hit the Z80 "W" monitor command (or QI Port ED or Out EE 01).  LED D7 should light up. (Also D2 and D3 but not D5). The Z80 will go into a hold state. With the power still on,  change the jumper K3 to K3 1-2.  All 4 LEDs should go off.
With Jumper K3  still 1-2.   Jumper P108 1-2. Repeat the above "W" command.
The 80386 Active  (D7), LED again light up.  (Also D2 and D3 but not D5)
Here is a picture of the board at this stage:-
    
 Step 2
    

If you do not get the above LED pattern do not go further until you resolve the problem.   Check the LED's are functional (take out U66 and ground the appropriate pins).  Check XFERI and XFERII are going low into K3. If not check your CPLD code.  You can use a the "Spare" LED D1 as a diagnostic indicator to show internal values in the CPLD code.  A LOW value will light up the LED D1.

With a logic probe check some of the pins on the CPU Socket.
       
 CPU Socket

The 80386_Reset pin (C9) should go from HIGH to LOW, and stay there,  with the above "W" command.
The CPU_HOLD pin (D14) should always be LOW
The READY* pin (G13) should also always be LOW
The CLK2 pin (F12) should pulse. If you have a scope it should have a frequency of 16MHz and look something like this (or better):-
  
 CLK2

Next carefully install the 80386 CPU. Repeat the above "W" test.  The same LED's should light up.
  
Next add U55 and U56. Jumper JP7 and JP8 if your front panel done not generate a MWRT and the 2MHz clock signal when a slave has the bus. 
Jumper K104 2-3 for now.
Add U102, U103, U113  and U114.
For now Jumper P2 9-10, P101 5-6, P11 9-10 and  P102 7-8.  Note that pin 1 is on the bottom of the jumper blocks.

Also keep in mind the delay jumper P101 (Delay_2), has always got to be less than P2 (RAM_Waits),  P11 (IO_Waits). 
Delay_2 is a jumper that shortens the length of the pWR* signal appearing on the S100 bus -- it stays too long from the 80386 for some RAM boards. It is quite different from the P101, P11 or P102 jumpers that simply add wait states to the CPU during each cycle.

Currently the wait state CPLD input Delay 1 is not used.  It is there in case there is a need for a short delay before a signal is put on the bus.  The first two pins of P102 are NOT connected to INTA.  Please see the schematic.
Here is a jumper picture:-
 
 Wait State Jumpers II
   
Jumper K2 1-2 (Pipeline Mode Off) for now. 
Install the four data bus buffers.  It's best to use 74LS645 buffers but 74LS245 buffers are fine as well.
Finally install U117, U4.  All the IC sockets should now be filled on the board.
Repeat the above "W" test.  The same LED's should light up.
Install K106 and K103 1-2 (Assuming you will be using the V2 Extended RAM Board), and K5 1-2. (The only time K5 is 2-3 is for our 8MG S100_OTT RAM Board).  Install K101-1 2-3 for now (16 Bits only).

Here is a picture of the board at this stage-
   
 Step 3

Insert the board into your system and use theZ80 monitor "O" command (or equivalent method), to transfer control to this slave 80386 board.  If you have a SMB (VI or VII), the HEX displays should show 0FFFF2 and the data EA34. NOTHING MORE WILL HAPPEN,  this is because the jumper K104 immediately and continuously sends wait states to the CPU.  If you remove this jumper the CPU should signon with the 80386 monitor (if you already have that installed in the two ROMs on your MSDOS Support board.  Note the board should also work perfectly fine (in Real Mode), with the 8086 monitor in these ROMs. Position the K104 jumper to its normal 2-3 position.

If you already have the 80386 monitor on the MSDOS support board you can boot it in "Protected Mode" mode by hitting again the "O" command. Do a memory map with the "A" command.  You should get a 16MB map with the ROM appearing at the top of each 1MG boundary see below.  Jumper K102 1-2, now the ROM should only appear at the top of the first 1MG boundary only as shown below. Here are two pictures using one of our 16MB RAM Boards.
  
 1M RAM MAP  16MB RAM MAP
 
From now on, if you are using the RAM with the S100-OTT bus (see below), make sure K102 is always jumpered 1-2 (16 or 32 bit data)

While you can boot MSDOS with this board and run any Real mode programs with the 8086 monitor, now would be a good time to switch up to the 80386 monitor.  It contains all the 8086 monitor code as well as the 80386 protected mode code.
 
If you are still in Protected mode hit the "O" command again to bring the CPU back to "Real Mode".  Hit the "P" command to boot up MSDOS. After you enter a CR you should get the following display.
  
 Boot MSDOS

You now are well on your way to having a fully functional S100 Bus 80386 board -- congratulations!

Debugging.
If your board does not come up as described above don't worry, this is a fairly complicated board there are many options you can take to narrow down what the problem is. 

First try lowering the S100 bus Phi clock signal. Use a 24 or 28MHz oscillator (for a 6 or 7  MHz Phi).  Real old boards may only work at even lower speeds but in general if the CPU does not even signon on at these speeds a lower Phi generally will not help.

The 80386 is actually quite tolerant in terms of reading bus data. Where it is fussy is in the phase relationships between CLK2 and CLK and a good clean reset signal.  If you have a good scope check the is no jitter in CLK2 and CLK. 

For hardware debugging purposes the 80386 (and 8086) monitors have an option that if after reset the IOBYTE port (port EFH), reads 00xxxxxxH the monitor will jump to a routine where it simply outputs 33H on the console output (port 01H).  If you do not have a SMB you can just burn a ROM with the following code.

E4EF        Start:  IN AL,IOBYTE
E601                OUT 1,AL
3CEF                CMP AL,0EFH
75F8                JNZ   Start
EA00050000          JMP   word 0H:500H   ;Jump to low RAM


Remember however the two ROMs are in Low Byte/ High Byte format.   So if you are using 28C256 EEPROMS,
at 7FF8 you should have:-
E4, E6, 3C, 75, EA, 05, 00  for the even bytes ROM and
EF, 01, EF, F8, 00, 00 for the odd bytes ROM.

If you are up to it,  instead you can use our Z80 CPU board to bring is the top 4K of the 1MG address space  and directly place the above code in RAM, this way not even the MSDOS support board is required.  The Z80 monitor commands would be:-

QO D2, FC
S3FF0   B0 33  E6  01  EB  FA BB


Hit the reset button and issue the "O" command.  You should see continuous "33333...." on the console.
Note for this application the MSDOS support board should not be present.

Actually in the most recent versions of the Z80 MASTER monitor this code is actually placed in RAM using the monitor "O" command before control is transferred to the 80386 board so removing the MSDOS support board will expose the above code.  Remember if the MSDOS Support board is present the onboard ROMs pull the  RAM board S100 bus Phantom line low and so inactivate RAM in the FC000-FFFFFH range.
 
Getting the board to produce "3333..." is the most basic requirement you can get.  If you get it you are well on your way to getting the board to work.  If you cannot get this working, repeat the above but jumper K104 back to 2-3.

Issue the "W" command.  The SMB Hex display must show 0FFFFF and the data bytes must be EAEF.  If not check your bus address buffers. Look at the data going into each gate and coming out of each gate. Check both U75, U74, U73 and U111, U107 and U108.  Check the odd and even bytes coming in from U104,U1006, U105 and U112.  Which buffer is active is complicated and requires a careful study of the Intel manual,  but the CPLD software should allow you to figure it out. 

Next flip the SMB stop switch to the stop position.  Remove the Jumper K104.  The above FFFF0 & EAEF display should not change. Then flip the single step switch on the SMB one flip at a time.   You should be able to step the CPU through the above code two bytes at a time. The HEX display should display the appropriate addresses and bytes. Because the 80386 buffers RAM data the CPU will cycle all the way from FFFF0 to FFFFF before going back to FFFF0.  At each loop a "3" should appear on your console.  If you cannot get the CPU to single step like this you need to carefully examine the critical board signals to identify where the problem is.    If you do not have the SMB you can temporary rig up a bounce less switch to do the above. See the SMB schematic for the circuit.

OK,  if you get the above to work but the monitor still does not come up you need to determine what the nature of the problem is.   You see in the  above code example that if while the CPU is in the "33333...." loop if you change the IOBYTE to anything other than 0EFH it will do a far jump to 500H in RAM.    Place F4H (the HALT opcode) at 500H in RAM first and do this. The CPU should HALT once you change any IOBYTE switch.  This shows you are at least doing a FAR JMP correctly.  From 500H in RAM you can key in simple code to read a port, modify RAM (bytes & words)  to further determine where the board problem resides. 

Another critical circuit is the monitor CPU address FFFFFFFF to 000FFFFF block switching circuit (so the same 8086 and 80386 ROMS can be used).
If you find the board boots MSDOS fine with K102 in the 2-3 position and not 1-2 position you may need a faster U107, U108, U110 and U110. Use 74Sxxx or 74Fxxx chips. 

The hardest problem to solve is interrupts.  MSDOS uses interrupts.  If the monitor seems to work fine but hangs when loading MSDOS check what is happening to interrupt requests.  The 80386 monitor has a few commands to see/test keyboard interrupts.  Putting one port I/O and INTA wait states on the board should be explored.

Adding S100-OTT Bus Memory
The final step in the assembly process is to add the two "Over the top" (OTT) connectors to add Protected Mode (PM) RAM access for memory above 16MB.  
The S100 bus has the capability to address 16MB of RAM with its 24 address lines.  The 80386 can address over 3GB of RAM with its 32 Address lines.  To add more RAM capability to the S100 bus system we use two cable connectors and a second RAM board.  We will call these connectors the S100-OTT bus.  The connections are such that multiple boards could be used with this S100-OTT bus.   Here is a list of the connections.
     
 S100-OTT Bus

Most of the pins are fairly straightforward.   This is a 32 bit bus. The S100-OTT Address Bus brings across the address lines directly from the CPU quickly. The data is valid when the Address Strobe (ADS*)  high and the can be latched on the rising edge of that signal.  The S100-OTT 32 bit Data Bus also come directly from the CPU.   For both buses it is assumed the is are buffers (bidirectional for data) on the receiving RAM board(s).

The RAM board(s) ignore any CPU cycles unless S100_SEL* is HIGH. Make sure K102 is always jumpered 1-2 (16 or 32 bit data)

The three control lines M_IO, W_R and D_C define whether the bus cycle is a RAM read or write cycle (assuming S100_SEL* is HIGH).    The first versions of the S100-OTT RAM boards decoded M_IO, W_R and D_C (corresponding to the 80386 M/IO*, W/R* and D/C* signals) on the RAM board.   On this 80386 V2 board the signals are decoded beforehand for speed on the CPU board (within the CPLD), yielding a "pure" RAM Read* or "RAM Write*" signal.  The Jumpers K103 and K106 allow the use of the older boards. But all future boards will use the new format since it is not CPU specific.

The Signal DB_WAIT originates on the S100_OTT RAM board. When low it sends wait state requests back to the CPU.  It is always has an Open Collector gate to allow multiple boards to reside on the S100-OTT bus.

The DB_Phantom* line (again Open Collector), acts the same as the S100 bus phantom* line.

Because the address, data and control lines go quickly and directly to RAM this 32 bit bus should be capable of running at higher speeds than the S100 bus. Currently with the code in our CPLD any access to the S100_OTT RAM runs at 16MHz (2X the S100 bus speed).    I actually prefer to run it at 14MHz (using a 28 MHz Oscillator) for absolutely solid reliability.  I use 1 wait state on this  V2 S100_OTT RAM board. I have not yet played around with the CPLD code for the S100-OTT RAM Read and Write signals.  Adding delays etc. may be required for higher speeds.

Testing RAM is critical.  There is a lot of it and even at these speeds a complete test of 32 MG takes over two hours.  Test a small amount of RAM first to save time. Say 2000000 to 200FFFF.  The test writes bytes, words and double words into RAM checking all the time writes did not change other areas of RAM.  These are launched from the 80386 Protected Mode "K" menu using the "J" command.
Here is the menu:-
       
 J Menu
    
The "T" menu option is also important.  The "T" routine relocates a small executable routine loop into PM mode RAM on the S100-OTT board and jumps to that routine.  It simply outputs a character on the console.  But is doing so rapidly and continuously flips back and forth between the S100 Bus (for I/O) and the S100-OTT bus.  This is a crucial and difficult test for the board because it is rapidly switching the CPU clock frequencies.

If your board passes these RAM tests you now have a fully functional board.  Congratulations -- enjoy 80386 PM programming on the S100 bus.
 
80386-II Jumper Table.
There are less than the usual number jumpers on this CPU board compare to our earlier boards.  That said, they need to be set carefully.  To run the board as a bus slave (with a Z80 master) with a PHI bus speed of  7.5 MHz (CPU CLK 15MHz) here is a typical jumper setup:-
         
 
Jumper   Function 
K21-2, Pipeline mode always on.  (2-3 to set pipeline mode in the CPLD code)
K101 Force the OTT bus access to 16 bit mode 1-2 (normally off i.e. 32 bit mode)
JP1, JP2, JP3 If your S-100 bus is IEEE-696 compatible these jumpers allow extra ground access to the board. Most S-100 busses don't have this installed 
JP4, JP5, JP6 Slave clear, POC & Reset are generated on this board (used only if board is set as a bus master)
P108 pHLDA to S100 bus. For slave configuration 1-2.
JP103 Closed, Pullup resistor for pHOLD.
K102 Normally 1-2. If 2-3 only 1MG of RAM is visible to the CPU.
JP11 Open, pullup resistor for pHLDA
K104 1-2 (high).  If low (2-3) CPU will immediately go to a continuous wait state upon assuming control of the bus. This is used for hardware debugging.
JP17,19,20 & 21 Normally all open unless the board is a bus master.
JP16 Normally unused.
K106, K103 Jumpers for CPLD Rd/Wr signals to OTT RAM board. Normally 1-2 for the V10 32/64MB RAM Board
JP101 Disable PHI input to CPLD. Used during the initial CPLD programming cycle where it is open. Normally closed.
K3 Normally 1-2 for board in Slave mode. 2-3 if bus master.
K107 HOLD* signal to S100 bus. For bus slave configuration 2-3.
K5CLK or CLK2 signal to OTT RAM board to clock wait states. Normally 1-2 for the V10 32/64MB RAM Board
P104 CPLD JTAJ04 programming socket for Rockfield Research 1508 programmer. Pin 1 is bottom left.
P2,P101,P11,P102 Wait state jumpers. See the above text.
RR3, RR2 In slave mode these pins are NOT connected to a pullup resistor network. In master mode use 1K pullups.
   
You can play around with the wait state jumpers. As I said above, if you are not using the OTT RAM board you can often push the CPU to  a 9 or 10MHz S100 PHI clock. After much trial and error this is what I ended up with for our OTT RAM access (V2/V10) board and a Phi of 7.5 MHz.
   
Jumpers-2
     
RAM Boards.
This CPU board seems to work fine with all our earlier RAM boards.  It tests out OK with old S100 bus RAM boards like the CompuPro RAM21 128K board, the Fulcrum 64K board or the Fulcrum Omni 256K RAM board.  These RAM boards must meet IEEE-696 specs and be able to handle 8 and 16 bit data. Old 8 bit only boards will not work.

The recommended boards to run with this CPU board is the V6 16MB RAM board and the V2/V10 S100-OTT 32/64MB RAM board.  The former has the 8 and 16 bit data buffers lined up to exactly match the four on this board.  The 32/64 MB board directly inputs the 80386 RAM read write signals and is again optimized for this board.  This 80386 setup should really be used as a 3 board set (the 80386 board, 16MB (V6) RAM board and the OTT 32/64MB RAM Board).  BTW, the V6 16MB RAM works with every other CPU board I have here on this site. It should be the last S100 bus RAM board you will ever need!

   
BUGS
The only bug I have noticed so far is the need for a 1K pull-up resistor on pin 8 of U49 to Vcc (see above). 

Because most S100 and S100-OTT bus signals are defined within  the CPLD there is much room to tweak the board for higher speeds and less wait states.  If you arrive at a different code option please let me know. I will post it here.  One thing to keep in mind,  if the board is to be used only on the S100 Bus (16MB RAM),  the bus Phi clock speed can easily go up to 9MHz in my system (a 36MHz oscillator and different CD0/CD1 dividers), however the 2X speed increase for the S100-OTT RAM leads to errors in the > 16M RAM test. 

I'm still playing around with Oscillators. The most reliable so far is a 60 MHz Oscillator. You should order a number of different oscillators if you can.  It's unclear to me why but lower speed oscillators (with smaller divides) do not seem to work as well.

For high speeds reliability see if you can use 74Sxxx or 74Fxxx 157's and a 133.  Also use 74LS645's instead of 74LS245's.

I have recently observed that the board is much more reliable for OTT access using Ti chips for the 74LS245's (or better 74LS645's).  I cannot stress enough the importance of using high quality 74xx chips.  There are few of them on this board but its function critically depends on them. Old chips are characterized by unreliable overnight OTT RAM checks.  Save yourself the frustration by getting new Ti chips from the likes of Mouser.

The original GAL code posted for the VGA Board in the VGA_SEL GAL only decoded the address range A19 - A0.  This was fine for the 8088 CPU.  However now that we have this board working with the 80386 CPU board we need to decode the full S100 bus range A23 - A0 so the boards ROM and RAM does not appear in every 1MB page when running the CPU in protected mode.   The changes are shown in yellow in the GAL code on this page. The VGA_GAL .ZIP files have also been corrected.  If you intend to use this board with any CPU that extends further than 1MB,  please correct the GAL code.

Also try and use connectors at the top of the board with built in ejectors as shown in the above picture of the board. You will be removing the overhead ribbon cable connections a lot. Pulling it out leads to bad connections.

The CPLD is from Mouser,  Part # 556-ATF-1508AS-10JU84
For 80386 its probably the easiest to buy a 80386 motherboard on eBay, check it  signs on and then pull the chip
.
I use AMD Am386 DX/DXL-40 chips.  The board will also work well with the later Intel CPU's. The earlier versions were internally dynamically refreshed and will not tolerate rapid clock speed switches.  Probably OK if you don't switch speeds for the OTT RAM. I have a board working fine with a 1985 Intel chip (A80386DX-25 IV, SX218, L0440373).


A Production S-100 Board
Realizing that a number of people might want to utilize a board like this together with a group of people on the  Google Groups S100Computers Forum, "group purchases" are made from time to time.  Contact and join the group if you would like to be involved in this project.  Please see here for more information.


The links below will contain the most recent schematic of this board.
Note, it may change over time and some IC part or pin numbers may not correlate exactly with the text in the article above.

The Intel 80386 Hardware Reference Manual

MOST CURRENT V2 80386 CPU BOARD SCHEMATIC  (V2 FINAL, 5/3/2016)
MOST CURRENT V2 80386 CPU  BOARD LAYOUT    (V2 FINAL, 5/3/2016)

Most current V2 80386 KiCAD files for this board  
(V2 FINAL, 5/3/2016)
Most current V2 80386 Gerber files for this board   (V2 FINAL, 5/3/2016)
MOST CURRENT V2 80386 CPU  BOARD GAL Code       
(12/20/2015)
MOST CURRENT V2 80386 CPU  BOARD CPLD Code (Slave mode)        (5/3/2016)
MOST CURRENT V2 80386 CPU  BOARD CPLD Code (Master mode)        (5/3/2016)

V2 80386 CPU  BOM List        (Supplied by Rick Bromagem, 1/20/2016)



Other pages describing my S-100 hardware and software.
Please click here to continue...

This page was last modified on 10/08/2022